#include"myserver.h"
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
static inline void msleep(unsigned long ms);
static inline void print_usage(char *progname);
int main(int argc, char **argv)
{
 int listenfd, connfd;
 int serv_port = 0;
 int daemon_run = 0;
 char *progname = NULL;
 int opt;
 fd_set rdset;
 int rv;
 int i, j;
 int found;
 int maxfd=0;
 char buf[1024];
 int fds_array[1024];
 struct option long_options[] =
 { 
 {"daemon", no_argument, NULL, 'b'},
 {"port", required_argument, NULL, 'p'},
 {"help", no_argument, NULL, 'h'},
 {NULL, 0, NULL, 0}
 }; 
 progname = basename(argv[0]);
 /* Parser the command line parameters */
 while ((opt = getopt_long(argc, argv, "bp:h", long_options, NULL)) != -1)
 { 
 switch (opt)
 { 
 case 'b':
 daemon_run=1;
 break;
 case 'p':
 serv_port = atoi(optarg);
 break;
 case 'h': /* Get help information */
 print_usage(progname);
 return EXIT_SUCCESS;
 default:
 break;
 } 
 } 
 if( !serv_port )
 { 
 print_usage(progname);
 return -1;
 }
 if( (listenfd=socket_server_init(NULL, serv_port)) < 0 )
 {
 printf("ERROR: %s server listen on port %d failure\n", argv[0],serv_port);
 return -2;
 }
 printf("%s server start to listen on port %d\n", argv[0],serv_port);
 /* set program running on background */
 if( daemon_run )
 {
 daemon(0, 0);
 }
 for(i=0; i<ARRAY_SIZE(fds_array) ; i++)
 {
 fds_array[i]=-1;
 }
 fds_array[0] = listenfd;
 for ( ; ; )
 {
 FD_ZERO(&rdset);
 for(i=0; i<ARRAY_SIZE(fds_array) ; i++)
 {
 if( fds_array[i] < 0 )
 continue;
  printf("66666\n");
 maxfd = fds_array[i]>maxfd ? fds_array[i] : maxfd;
 FD_SET(fds_array[i], &rdset);
 }
 /* program will blocked here */
 printf("666663\n");
 rv = select(maxfd+1, &rdset, NULL, NULL, NULL);
 printf("666664\n");
 if(rv < 0)
 {
 printf("select failure: %s\n", strerror(errno));
 break;
 }
 else if(rv == 0)
 {
 printf("select get timeout\n");
 continue;
 }
 printf("666660\n");
 /* listen socket get event means new client start connect now */
 if ( FD_ISSET(listenfd, &rdset) )
 {
  printf("666661\n");
 if( (connfd=accept(listenfd, (struct sockaddr *)NULL, NULL)) < 0)
 {
 printf("accept new client failure: %s\n", strerror(errno));
 continue;
 }
  printf("666662\n");
 found = 0;
 for(i=0; i<ARRAY_SIZE(fds_array) ; i++)
 {
 if( fds_array[i] < 0 )
 {
 printf("accept new client[%d] and add it into array\n", connfd );
 fds_array[i] = connfd;
 found = 1;
 break;
 }
 }
 if( !found )
 {
 printf("accept new client[%d] but full, so refuse it\n", connfd);
 close(connfd);
 }
 }
 else /* data arrive from already connected client */
 {
// printf("66666\n");
 for(i=0; i<ARRAY_SIZE(fds_array); i++)
 {
 if( fds_array[i]<0 || !FD_ISSET(fds_array[i], &rdset) )
 continue;
 
 if( (rv=read(fds_array[i], buf, sizeof(buf))) <= 0)
 {
 printf("socket[%d] read failure or get disconncet.\n", fds_array[i]);
 close(fds_array[i]);
 fds_array[i] = -1;
 }
 else
 {
 printf("socket[%d] read get %d bytes data\n", fds_array[i], rv);
 /* convert letter from lowercase to uppercase */
 for(j=0; j<rv; j++)
 buf[j]=toupper(buf[j]);
 if( write(fds_array[i], buf, rv) < 0 )
 {
 printf("socket[%d] write failure: %s\n", fds_array[i], strerror(errno));
 close(fds_array[i]);
 fds_array[i] = -1;
 }
 }
 }
 }
 }
CleanUp:
 close(listenfd);
 return 0;
}
static inline void msleep(unsigned long ms)
{
 struct timeval tv;
 tv.tv_sec = ms/1000;
 tv.tv_usec = (ms%1000)*1000;
 
 select(0, NULL, NULL, NULL, &tv);
}
static inline void print_usage(char *progname)
{
 printf("Usage: %s [OPTION]...\n", progname);
 
 printf(" %s is a socket server program, which used to verify client and echo back string from it\n",
progname);
 printf("\nMandatory arguments to long options are mandatory for short options too:\n");
 
 printf(" -b[daemon ] set program running on background\n");
 printf(" -p[port ] Socket server port address\n");
 printf(" -h[help ] Display this help information\n");
 
 printf("\nExample: %s -b -p 8900\n", progname);
 return ;
}
